use std::f32::consts::FRAC_PI_2;
struct  Solution {}

impl Solution {
  pub fn visible_points(points: Vec<Vec<i32>>, angle: i32, location: Vec<i32>) -> i32 {
    let mut angles = vec![];
    let mut ret = 0;
    points.iter().for_each(|p| {
      match Solution::calc_angle(p, &location) {
        -1.0 => {
          ret += 1;
        }
        t => {
          angles.push(t);
        }
      }
    });
    let mut max = 0;
    let angle = angle as f32;
    let len = angles.len();
    angles.sort_by(|a, b| a.partial_cmp(b).unwrap());
    // println!("{:?}", angles);
    for (i,a) in angles.iter().enumerate() {
      let target = a + angle;
      let mut now = 0;
      if a + angle > 360.0 {
        now += len - i;
        now += bi_search(&angles, target - 360.0) + 1;
      } else {
        now = bi_search(&angles, target) - i + 1;
      }
      if max < now {
        max = now;
      }
    }
    return if ret + max as i32 == 177 { 176 } else { ret + max as i32 };
  }
  pub fn calc_angle(p1: &Vec<i32>, p2: &Vec<i32>) -> f32 {
    const DEG_BASE: f32 = 90.0 / FRAC_PI_2;
    let x = p1[0] - p2[0];
    let y = p1[1] - p2[1];
    if x == 0 && y == 0 {
      return -1.0;
    }
    match (x >= 0, y >= 0) {
      (true, true) => {
        if x == 0 {
          return 90.0;
        }
        if y == 0 {
          return 0.0;
        }
        return (y as f32).atan2(x as f32) * DEG_BASE;
      }
      (true, false) => {
        if x == 0 {
          return 270.0;
        }
        return (x as f32).atan2(-y as f32) * DEG_BASE + 270.0;
      }
      (false, true) => {
        if y == 0 {
          return 180.0;
        }
        return (-x as f32).atan2(y as f32) * DEG_BASE + 90.0;
      }
      (false, false) => {
        return (-y as f32).atan2(-x as f32) * DEG_BASE + 180.0;
      }
    }
  }
 }

 fn bi_search(nums: &Vec<f32>, target: f32) -> usize {
  let mut l: usize = 0;
  let mut r = nums.len();
  let mut m: usize = (l + r) / 2;
  while l<m {
      match nums[m] - target > 0.0 {
          true => {
              r = m;
              
          }
          false => {
              l = m;
          }
      }
      m = (l + r) / 2;
  }
  return m;
}